#include <structure.h>
#include <OSProc.h>
#include <IPC/LibMemory.h>
#include <IPC/streamIO.h>
using namespace LibMemory;

namespace LazyLib
{

typedef struct
{
  _pcb* pro;
  _ptlong* (*alloc)(_ptlong);
  _ptlong* (*free)(_ptlong);
  _ptlong* (*item_alloc)(_ptlong);
  listnode<1> head;
  listnode<1> tail;
}_llibs;
}
using namespace LazyLib;
static int _UnloadLib(_llibs* libs)
{
  listnode<1>* old = (libs->tail.pre);
  if(old == &(libs->head))
    return 0;
  _libs* oold = (_libs*)(old->mark[0]);
  return (RemoveLibMemory(oold,libs->pro) != 0
	  ? (RemoveListNode(old),1)
	  : 0);
}

namespace LazyLib
{


  _llibs* InitLazyLib(_llibs* lazylib,_pcb* owner,_ptlong*(*item_alloc)(_ptlong),_ptlong* (*alloc)(_ptlong),_ptlong* (*free)(_ptlong))
  {
    lazylib->pro = owner;
    lazylib->alloc = alloc;
    lazylib->free = free;
    lazylib->item_alloc = item_alloc;
    MakeListNode(&(lazylib->head),NULL);
    MakeListNode(&(lazylib->tail),NULL);
    InsertListNode(&(lazylib->head),&(lazylib->tail));
  }

  _libs* LoadLib(_llibs* llib,_fstr file)
  {
    _length num;
    listnode<1>* node = &(llib->head);
    while(node != &(llib->tail))
      {
	if(((_libs*)(node->mark[0]))->file == file)
	  {
	    RemoveListNode(node);
	    return (_libs*)(node->mark[0]);
	  }
	node =node->next;
      }
    
    _ptlong* vAddr = llib->alloc( num = GetLengthStream(file));
    while(vAddr = NULL)
      {
	if(_UnloadLib(llib) == 0)
	  return 0;
	vAddr = llib->alloc(num);
      }
    
    return FileStreamToLibMemory(file,llib->pro,vAddr,num,0);
  }
  int UnloadLib(_llibs* llib,_libs* lib)
  {
    InsertListNode(&(llib->head),MakeListNode((listnode<1>*)llib->item_alloc(sizeof(listnode<1>)),lib));
    
  }
}




